웹 브라우저의 동작
✒️ 2025-05-30 09:47 내용 수정
원본 자료 : mdn web docs 웹 브라우저 동작
- 위 문서를 읽고 개인적으로 이해하기 쉬운 내용을 첨가 및 수정, 재배치하여 정리했다.
왜 동작을 알아야 할까
개발자는 웹 브라우저의 동작을 이해함으로써 웹 최적화를 적용한 웹 사이트를 제공하여 사용자의 웹 경험을 개선할 수 있다.
- 빠른 사이트를 위한 웹 성능에 있어 중요한 문제는 지연 시간과 브라우저의 싱글 쓰레드 동작이다.
- 사용자와 빠르게 요청을 주고 받으며, 페이지 로드가 최대한 빨리 이루어져야 한다.
- 웹 브라우저는 싱글 쓰레드로 동작하기에 메인 쓰레드의 부담을 줄여주면서 유저와의 원활한 상호작용을 위해 렌더링 시간이 오래 걸리지 않도록 해야 한다.
1. 탐색(Navigation)
- 사용자가 주소창에 URL을 입력하거나 폼을 제출하는 등 동작을 통해 요청을 보낼 때 발생한다.
- 웹 최적화의 조건 중 하나는 탐색이 완료될 때까지의 시간을 최소화하여 지연 시간을 줄이는 것이다.
탐색 과정
DNS 조회 -> TCP 핸드셰이크 -> TLS 협상
DNS 조회
DNS 참고.
- 사용자가 웹 페이지를 요청하면 브라우저는 먼저 해당 페이지의 자원이 어디 있는지 찾는다.
- 브라우저는 DNS 조회를 요청하고, 이름 서버는 이 요청을 받아 IP 주소로 응답한다.
www.test.com->000.000.000.000으로 변환
- 최초 요청 후 IP는 일정 시간 동안 브라우저나 운영체제 등에 일정 시간 동안 저장(캐시) 한다.
- 이후 캐시된 IP를 사용하여 후속 요청 속도를 높인다.
🛠️ 발생할 수 있는 문제점 및 주의점
- DNS 조회는 호스트 이름 하나 당 한 번만 수행되므로, 요청된 페이지에서 참조하는 다른 호스트 이름에 대해서는 각각 요청을 수행한다.
- 아래 예시라면 총 2번의 DNS 조회가 일어난다.
- 이후 같은 세션 내에서 두 도메인의 IP는 캐시되어 DNS 재조회를 하지 않는다.
<html>
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
</head>
<body>
<img src="https://images.example.net/photo.jpg">
</body>
</html>
- 웹 페이지에 너무 많은 도메인 주소가 있다면 각각의 주소마다 DNS 조회를 수행한다.
- 이 경우 모바일 네트워크 환경에선 웹 페이지에 있는 도메인에 대한 DNS 조회를 요청할 때마다 휴대폰과 셀 타워, 이름 서버 간에 요청/응답을 주고받아야 하므로 상당한 지연이 생길 수 있다.
TCP 핸드셰이크와 TLS 협상
- 브라우저가 IP 주소를 확인한 후엔 서버와 TCP 3방향 핸드셰이크를 통해 연결을 설정한다.
- TCP 3방향 핸드셰이크 : TCP는 TCP 세션을 협상하고 시작하기 위해 3가지 메시지(SYN, SYN-ACK, ACK)를 사용하여 IP 기반 네트워크를 통해 TCP/IP 연결을 설정한다.
- TCP 핸드셰이크 후 브라우저와 서버는 HTTPS를 이용한 보안성 있는 연결인 TLS 협상을 진행한다.
- TLS : 디지털 인증서를 제공하도록 요구하여 네트워크 상에서 안전하게 통신하기 위해 사용된 네트워크 보안 프로토콜
🛠️ 발생할 수 있는 문제점 및 주의점
- 보안이 적용된 연결을 생성하기 위해 실제 자원을 요청하기까지 시간이 걸리기 때문에 페이지 로딩이 오래 걸린다.
- 그러나 보안이 적용되지 않는다면 브라우저와 웹 서버 사이에서 전송되는 데이터가 제 3자에 의해 해독되는 등의 보안 문제가 발생할 수 있어 보안 적용은 지연 시간을 감수할 가치가 충분히 있다.
2. 응답(Response)
- 탐색의 과정을 거쳐 브라우저와 웹 서버가 연결되면 브라우저는 유저 대신에 초기 HTTP GET request 요청을 보낸다.
- 서버는 요청을 받으면 관련 응답 헤더와 함께 자원을 브라우저로 전송한다.
- 데이터를 주고 받을 때 TCP 패킷은 전송 중에 세그먼트로 분할된다.
- TCP의 순서 보장 특성으로 인해 일정 개수의 세그먼트를 보낸 후 클라이언트로부터 ACK 패킷 형태로 승인을 받아야 한다.
- 이 과정에서 네트워크 환경에 따라 전송되는 세그먼트 수의 균형을 맞추기 위해 TCP 슬로우 스타트 알고리즘을 사용한다.
- TCP 슬로우 스타트 : 패킷 전송에 사용 가능한 대역폭을 감지하고 네트워크 연결 속도의 균형을 맞추는 알고리즘이다.
3. 구문 분석(Parsing)
- 브라우저가 네트워크를 통해 서버로부터 받은 데이터를 DOM이나 CSSOM으로 바꾸는 단계다.
- HTML, CSS, JavaScript 등을 분석하여 Object Model 트리를 생성하고, 스크립트를 컴파일하는 코드 분석 과정이다.
- DOM(Document Obejct Model) : HTML 또는 XML 기반 문서와 상호작용하고 표현하는 API
- CSSOM(CSS Obejct Model) : CSS 정보를 읽고 수정하기 위한 API 세트
- 두 구조 모두 트리 구조이며 각각의 독립적인 자료 구조다.
- 브라우저가 구문 분석을 마치면 렌더러에서 화면에 페이지를 그리는 데 사용한다.
DOM 트리 구축
- HTML을 처리하여 시작 및 종료 태그, 속성 이름 및 값이 포함된 HTML 토큰을 만든다.
- 구문 분석기는 토큰을 사용하여 DOM 트리를 생성하여 문서에 포함된 태그 간의 관계와 계층을 반영한다.
- DOM 트리를 만드는 작업은 메인 쓰레드를 차지한다.
🛠️ 발생할 수 있는 문제점 및 주의점
- HTML 문서가 잘 구성되지 않으면 구분 분석에 시간이 걸릴 수 있다.
- DOM 노드의 개수가 많아질 수록 DOM 트리를 만드는 데 시간이 오래 걸릴 수 있다.
async나defer와 같은 설정이 적용되지 않은<script>태그는 렌더링을 막고 HTML 분석을 중지 시키기에 병목 구간이 될 수 있다.
프리로드 스캐너(Preload scanner)
- 프리로드 스캐너는 사용 가능한 컨텐츠를 분석하여 외부 자원을 뒤에서 미리 요청한다.
- CSS, JavaScript, 웹 폰트와 같이 우선순위가 높은 자원을 요청하며, 자원을 미리 받아두기에 블로킹을 줄여준다.
CSSOM 구축
- HTML 토큰으로 DOM 트리를 구축한 것처럼 CSS를 처리하여 CSSOM 트리를 만든다.
- 브라우저는 CSS 규칙을 읽어 작업을 진행할 수 있도록 스타일 맵으로 변환하고, 트리 노드를 생성한다.
- 노드에 적용 가능한 가장 일반적인 규칙부터 세부적으로 적용된 규칙으로 스타일을 수정한다.
- CSSOM을 구축하는 시간은 매우 짧게 걸리기에 웹 성능 최적화 관점에서 크게 기여할 수 있는 영역은 아니다.
JavaScript 컴파일
- CCSOM이 생성되는 동안 프리로드 스캐너는 JavaScript 파일과 같은 자원을 다운로드한다.
- 스크립트는 추상 구문 트리로 구문 분석되며, 메인 쓰레드에서 실행되는 바이트 코드를 생성하는 컴파일 과정을 거친다.
접근성 트리 구축(Accessibility Tree)
- 브라우저는 접근성 트리를 생성하고, 보조 장치는 이 트리를 이용해 내용을 분석하고 해석한다.
- 접근성 : 모든 사용자가 웹에 접근하는 방식에 상관없이 모든 기능과 컨텐츠를 사용할 수 있는 것.
- 신체적, 정신적 장애가 있거나 이를 위한 보조 장치 이용에도 문제가 없어야 한다.
- 접근성 : 모든 사용자가 웹에 접근하는 방식에 상관없이 모든 기능과 컨텐츠를 사용할 수 있는 것.
- DOM이 업데이트 될 때 접근성 트리도 업데이트한다.
4. 렌더(Render)
브라우저 렌더링 참고
- 구문 분석의 결과를 토대로 웹 페이지에 내용물을 직접 그리는 단계다.
- DOM 트리와 CSSOM 트리는 구문 분석되는 과정에서 생성되고 렌더 트리로 합성되고, 렌더 트리는 보이는 요소의 레이아웃을 계산한다.
- 레이아웃을 계산한 뒤엔 요소가 화면에 그려진다.
- 화면의 일부분을 CPU 대신 GPU가 그리면서 메인 쓰레드의 부담이 줄고 성능이 향상된다.
스타일(Style)
- 렌더 트리(계산된 스타일 트리) : DOM 트리의 루트부터 시작하여 눈에 보이는 노드를 순회하고 각각의 보이는 노드에 적용된 CSSOM 규칙을 적용하여 만들어진다.
- 눈에 보이는 노드를 순환하기 때문에
<head>와 그 자식 요소,visibility: hidden속성을 가진 요소 등은 렌더 트리에 포함되지 않는다.
레이아웃(Layout)
- 렌더 트리를 만든 후에 레이아웃이 시작되며, 렌더 트리의 루트부터 시작하여 각 객체의 정확한 크기와 위치를 결정한다.
- 레이아웃 : 렌더 트리에 있는 모든 노드의 너비, 높이, 위치를 결정하는 프로세스다.
- 처음에 노드의 사이즈와 위치를 결정한다.
- 레이아웃 : 렌더 트리에 있는 모든 노드의 너비, 높이, 위치를 결정하는 프로세스다.
- 크기를 모르는 이미지와 같은 요소들의 위치와 크기 결정을 리플로우 때 진행한다.
- 리플로우 : 레이아웃 이후에 있는 페이지의 일부분이나 전체 문서에 대한 크기나 위치에 대한 결정이다.
페인팅(Painting)
- 레이아웃 단계에서 계산된 정보로 화면에 모든 요소의 시각적 부분을 그리는 단계다.
- 매우 빠르게 처리되어야 하는 단계다.
- 페인팅은 레이아웃 트리의 요소를 레이어로 분리할 수 있으며, 컨텐츠를 CPU 메인 쓰레드에서 GPU 레이어로 격상하는 것은 페인트 및 리페인트 성능을 높인다.
- 레이어는
<video>,<canvas>같은 요소와opacity, 3Dtransform,will-change같은 속성으로 가동된다.
- 레이어는
🛠️ 발생할 수 있는 문제점 및 주의점
- 레이어는 성능을 향상 시키지만 메모리 관리 측면에선 비싼 작업이므로, 웹 성능 최적화를 위해선 과도하게 쓰이지 않아야 한다.
합성(Compositing)
- 문서의 여러 레이아웃들을 올바른 순서로 배치하고 정확하게 렌더하는 단계다.
- 페이지가 자원을 계속 로드할 때 리플로우가 발생할 수 있으며, 리플로우는 리페인트와 재합성을 일으킬 수 있다.
- 리페인트 후에 필요 시엔 재합성을 진행하거나 리페인트만 될 수도 있다.
- 크기를 지정하지 않은 이미지와 같은 자원이 도착할 경우 렌더 단계는 레이아웃부터 다시 진행된다.
5. 상호작용(Interactivity)
- 페이지 요청부터 화면에 그려지는 과정까지 완료되더라도 상호작용을 시작하는 데는 약간의 시간이 걸린다.
- Time To Interactive(TTI) : DNS 조회와 SSL 연결이 이루어지는 첫 요청부터 페이지가 상호작용할 준비가 될 때까지 얼마나 걸리는지 측정하는 단위다.
- 첫 번째 컨텐츠가 포함된 페인트 이후 페이지가 사용자와의 상호작용에 50ms 이내로 응답할 때를 상호작용이 가능한 시점으로 본다.
- 메인 쓰레드가 구문 분석, 컴파일 등을 진행하고 있으면 상호작용을 할 수 없기 때문에 TTI는 증가한다.
🛠️ 발생할 수 있는 문제점 및 주의점
- 웹 페이지의 구성이 메인 쓰레드의 점유율을 높이거나 네트워크를 느리게 만드는 경우 사용자와의 상호작용 시간이 느려질 수 있다.